# 构建邮件头
import smtplib

import aiosmtplib
from pydantic import BaseSettings
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart


class MailClient:
    '''
    用法示例：
    if __name__ == '__main__':
    MailClient(configs=MailClient.Config(MAIL_SERVER='SDSD')).sync_send_email()
    '''

    # 使用哪一个邮箱服务发送
    class Config(BaseSettings):
        # 使用哪一个邮箱服务发送
        MAIL_SERVER: str
        # 服务端口
        MAIL_PORT: int
        # 发送邮件使用的账号
        MAIL_USERNAME: str
        # 发送邮箱使用的秘钥（非邮箱密码）如：QQ 邮箱授权码
        MAIL_PASSWORD: str
        # 是否启用TLS
        MAIL_TLS: bool = True

    def __init__(self, settings: Config):
        self.settings = settings

    async def async_send_email(self, send_to_addr: str, contest_msg: str, msg_subject: str = None,
                               headerfrom: str = None,
                               files: list = None, headerto: str = None):
        # 连接发信服务器
        server = aiosmtplib.SMTP(hostname=self.settings.MAIL_SERVER, port=self.settings.MAIL_PORT,
                                 use_tls=self.settings.MAIL_TLS)
        # 建立连接--qq邮箱服务和端口号
        await server.connect()
        # 登入邮箱
        await server.login(self.settings.MAIL_USERNAME, self.settings.MAIL_PASSWORD)
        # 配置邮件正文内容

        msg = MIMEMultipart()
        msg['From'] = Header(headerfrom)  # 设置来自于邮件的发送者信息
        msg['To'] = Header(headerto)  # 设置来自于邮件的接收人信息
        msg['Subject'] = Header(msg_subject, 'utf-8')  # 设置邮件主题
        # 邮件正文内容
        msg.attach(MIMEText(contest_msg, 'html', 'utf-8'))

        # 构造附件1，传送文本附件
        if files:
            for file_name in files:
                # 发图片
                if file_name.endswith('jpg'):
                    image_file = MIMEImage(open(file_name, 'rb').read())
                    image_file.add_header('Content-Type', 'application/octet-stream')
                    image_file.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', file_name))
                    msg.attach(image_file)
                else:
                    test_file_att = MIMEText(open(file_name, 'rb').read(), 'base64', 'utf-8')
                    test_file_att["Content-Type"] = 'application/octet-stream'
                    test_file_att["Content-Disposition"] = f'attachment; filename="{file_name}"'
                    msg.attach(test_file_att)

        await server.sendmail(self.settings.MAIL_USERNAME, send_to_addr, msg.as_string())
        # 关闭服务器
        await server.quit()

    def sync_send_email(self, send_to_addr: str, contest_msg: str, msg_subject: str = None, headerfrom: str = None,
                        files: list = None, headerto: str = None):

        # 连接发信服务器
        server = smtplib.SMTP_SSL(self.settings.MAIL_SERVER)
        # 建立连接--qq邮箱服务和端口号
        server.connect(self.settings.MAIL_SERVER, self.settings.MAIL_PORT)
        # 登入邮箱
        server.login(self.settings.MAIL_USERNAME, self.settings.MAIL_PASSWORD)

        msg = MIMEMultipart()
        msg['From'] = Header(headerfrom)  # 设置来自于邮件的发送者信息
        msg['To'] = Header(headerto)  # 设置来自于邮件的接收人信息
        msg['Subject'] = Header(msg_subject, 'utf-8')  # 设置邮件主题
        # 邮件正文内容
        msg.attach(MIMEText(contest_msg, 'html', 'utf-8'))

        # 构造附件1，传送文本附件
        if files:
            for file_name in files:
                # 发图片
                if file_name.endswith('jpg'):
                    image_file = MIMEImage(open(file_name, 'rb').read())
                    image_file.add_header('Content-Type', 'application/octet-stream')
                    image_file.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', file_name))
                    msg.attach(image_file)
                else:
                    test_file_att = MIMEText(open(file_name, 'rb').read(), 'base64', 'utf-8')
                    test_file_att["Content-Type"] = 'application/octet-stream'
                    test_file_att["Content-Disposition"] = f'attachment; filename="{file_name}"'
                    msg.attach(test_file_att)

        server.sendmail(self.settings.MAIL_USERNAME, send_to_addr, msg.as_string())
        # 关闭服务器
        server.quit()
